/* eslint-disable max-len */
/* eslint-disable no-use-before-define */
/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { computed, defineComponent, onMounted, ref, SetupContext } from 'vue';
import { discussionEditorProps, DiscussionEditorProps } from './discussion-editor.props';
import { MsgInfo, editAttachFile } from './src/types/interface';
import FInputGroup from '../input-group/src/input-group.component';
import { LocaleService } from '../locale/src/lib/locale.service';
import { useDiscussionEditor } from './src/composition/use-discussion-editor';
import './discussion-editor.scss';

export default defineComponent({
    name: 'FDiscussionEditor',
    props: discussionEditorProps,
    emits: ['selections', 'lineData', 'value', 'filePreview', 'fileRemove', 'fileUploadDone', 'personnelSearch', 'getOutUsers'] as (string[] & ThisType<void>) | undefined,
    setup(props: DiscussionEditorProps, context: SetupContext) {
        const cancelVisible = ref(props.cancelVisible);
        const personnelsPrimaryKey = ref(props.personnelsPrimaryKey);
        const replyPersonnelsDisplayKey = ref(props.replyPersonnelsDisplayKey);
        const editHeight = ref(props.editHeight);
        const type = ref(props.type);
        const orgUrl = ref(props.orgUrl);
        const sectionData = ref(props.sectionData);

        let options: any;
        let placeholder: string;
        /** 暂存文本框的输入，解决焦点问题 */
        let tempTextValue: string;

        /** 人事弹窗列表数据 */
        const _personnels = ref(props.personnels);

        const personnels = computed({
            get() {
                return _personnels.value;
            },
            set(val) {
                if (val) {
                    _personnels.value = val;
                    innerPersonnels = _personnels.value;
                    copyPersonnels = _personnels.value;
                }
            }
        });

        /** 人事弹窗列表数据 */
        const _replyUser = ref(props.replyUser);

        const replyUser = computed({
            get() {
                return _replyUser;
            },
            set(val: any) {
                if (val) {
                    _replyUser.value = val;
                    if (_replyUser.value.id) {
                        editorFocus();
                    }
                }
            }
        });

        const _attachFiles = ref(props.attachFiles);

        const attachFiles = computed({
            get() {
                return _attachFiles.value;
            },
            set(val: any) {
                if (val) {
                    _attachFiles.value = val;
                }
            }
        });

        /** 审批意见 */
        const textValue = ref('');

        /** 暂存人员信息 */
        const tempPersonnelsValue = ref('');
        /** 暂存部门 */
        const tempSectionValue = ref('');

        /** 选择要发送的部门 */
        const selectedSection: any = [];
        /** 搜索文本框中绑定的值 */
        let personnelText: any;
        /** 暂存人员信息，用于搜索 */
        let copyPersonnels: any = [];
        let innerPersonnels: any = [];
        // let el: ElementRef;
        /** 避免重复输入的token */
        let token: boolean;
        let permission: any;
        /** 上传附件是否显示 */
        const attachFilesModalVisible = ref(false);
        const searchPersonnelList: any = {};
        const showSearchList = ref(false);
        const permissionList = ref();
        let localeService: LocaleService;
        const groupIcon = '<span class="f-icon f-icon-search"></span>';

        const { personSearchUrl, personnelsDisplayKey, personModalVisible, relativeVisible, selectedPersonnels,
            stopBubble, _isInArray, getSearchData, getAvatar, setRelativeValue } =
            useDiscussionEditor(props, context);
        onMounted(() => {
            document.addEventListener('click', setRelativeValue);
            permissionList.value = [
                { value: 'ALL', text: LocaleService.getLocaleValue('discussionGroup.all') },
                { value: 'RELATED', text: LocaleService.getLocaleValue('discussionGroup.related') }
            ];
            permission = permissionList.value[0];
            options = { maxUploads: 3, maxFileSize: 10240, allowedContentTypes: ['.jpg', '.pdf'] };
            placeholder = LocaleService.getLocaleValue('discussionGroup.placeholder');
        }
        );

        /** 文本框失去焦点触发 */
        function setTextValue(e: any) {
            if (e) {
                tempTextValue = e.target.innerHTML;
                textValue.value = tempTextValue;
            }
            if (tempPersonnelsValue.value) {
                textValue.value += tempPersonnelsValue.value;
            }
            if (tempSectionValue.value) {
                textValue.value += tempSectionValue.value;
            }
            tempTextValue = '';
            tempPersonnelsValue.value = '';
            tempSectionValue.value = '';
        }
        /** 监听键盘事件, 主要是用于删除@人 */
        function listenEditorValueChange(e: any) {
            tempTextValue = e.target.innerHTML;
            const { children } = e.target;
            const childrenId: any = [];
            for (let i = 0; i < children.length; i++) {
                childrenId.push(children[i].id);
            }
            selectedPersonnels.value.forEach((personnel: any, index: any) => {
                if (!childrenId.includes(personnel[personnelsPrimaryKey.value])) {
                    selectedPersonnels.value.splice(index, 1);
                }
            });
            selectedSection.value.forEach((section: any, index: any) => {
                if (!childrenId.includes(section[personnelsPrimaryKey.value])) {
                    selectedSection.value.splice(index, 1);
                }
            });
            if (!tempTextValue) {
                tempTextValue = '';
            }
        }
        /**
         * 搜索人员
         */
        function searchPersonnel() {

            if (personnelText) {
                showSearchList.value = true;
                getSearchData(personnelText, 0).subscribe((d: any) => {
                    if ("users" in d) {
                        searchPersonnelList.value = d;
                        setPersonModalPosition();
                    }
                });
            }
            else {
                showSearchList.value = false;
            }

        }
        /**
         * 搜索下一页
         */
        function getMoreSearchData() {
            getSearchData(personnelText, searchPersonnelList.pageIndex + 1).subscribe((d: any) => {
                if ("users" in d) {
                    searchPersonnelList.pageIndex = d.pageIndex;
                    searchPersonnelList.users = [...searchPersonnelList.users, ...d.users];
                }
            });
        }

        /** 增加 @ 人员 */
        function appendPersonnels() {
            let selectedList = [];
            if (!showSearchList.value) {
                selectedList = innerPersonnels.filter((item: any) => { item.active === true; });
            }
            else {
                selectedList = searchPersonnelList.users.filter((item: any) => item.active === true);
            }
            if (selectedList.length) {
                appendPersonnel(selectedList);
            }
            resetPersonnels();
            setTextValue(null);
            personModalVisible.value = false;
        }
        /** 高级搜索人员添加 */
        function appendPersonnelsList(listData: any) {
            if (listData.length) {
                appendPersonnel(listData, true);
            }
            setTextValue(null);
        }
        /** 循环增加人员 */
        function appendPersonnel(listData: any, external = false) {
            listData.forEach((item: any) => {
                if (!(selectedPersonnels.value.length && _isInArray(item[personnelsPrimaryKey.value], personnelsPrimaryKey.value, selectedPersonnels))) {
                    tempPersonnelsValue.value += '<a name="personnel" contenteditable="false" class="at-user" id="' + item[personnelsPrimaryKey.value] + '" userid="' + item[personnelsPrimaryKey.value] + '">@' + item[personnelsDisplayKey.value] + '</a>&nbsp;';
                    selectedPersonnels.value.push(item);
                }
            });
        }
        /**
         * 添加部门
         * @param listData
         */
        function appendSectionList(listData: any) {
            if (listData.length) {
                appendSection(listData);
            }
            setTextValue(null);
        }

        function appendSection(listData: any) {
            listData.forEach((item: any) => {
                if (!(selectedSection.value.length && _isInArray(item[personnelsPrimaryKey.value], personnelsPrimaryKey.value, selectedSection))) {
                    tempSectionValue.value += '<a name="org" contenteditable="false" class="at-org" id="' + item[personnelsPrimaryKey.value] + '" orgid="' + item[personnelsPrimaryKey.value] + '">@' + item.name + '</a>&nbsp;';
                    selectedSection.value.push(item);
                }
            });
        }

        /**
         * 关闭人事管理弹窗
         */
        function resetPersonnels() {
            showSearchList.value = false;
            personModalVisible.value = false;
            innerPersonnels = copyPersonnels;
            if (innerPersonnels.length) {
                innerPersonnels.forEach((item: any) => { item.active = false; });
            }
            personnelText = '';
        }

        /**
         * 打开人员管理
         * @param e 事件
         */
        function openModalPerson(e: any) {
            personModalVisible.value = !personModalVisible.value;
            setTimeout(() => {
                if (personModalVisible.value) {
                    setPersonModalPosition();
                }
            }, 0);
            stopBubble(e);
        }
        const personModal = ref<HTMLElement | null>(null);
        function setPersonModalPosition() {
            const winH = window.innerHeight;
            const ModalBottom = personModal.value?.getBoundingClientRect().bottom;
            if (ModalBottom && winH < ModalBottom) {
                personModal.value?.scrollIntoView(false);
            }
        }

        /**
         * 提交评语
         */
        function submitApproval() {
            if (!textValue.value) {
                const notEmptyText = LocaleService.getLocaleValue('discussionGroup.notEmpty');
                if (notEmptyText) {
                    // notifyService.error(notEmptyText);
                }
                return;
            }
            const editAttachFiles: editAttachFile[] = [];
            if (attachFiles.value && attachFiles.value.length) {
                attachFiles.value.forEach((file: any) => {
                    const { id } = file;
                    const { name } = file;
                    const { size } = file;
                    const { metadataId } = file.extend;
                    const attachFile = {
                        id,
                        name,
                        size,
                        metadataId
                    };
                    editAttachFiles.push(attachFile);
                });
            }
            context.emit('value', {
                msgInfo: MsgInfo.Confirm,
                text: textValue,
                mailTos: selectedPersonnels,
                mailToSections: selectedSection,
                visibility: permission.value,
                parentId: (replyUser.value && 'id' in replyUser.value) ? replyUser.value.id : null,
                attachFiles: editAttachFiles.length ? editAttachFiles : null
            });
            textValue.value = '';
            selectedPersonnels.value = [];
            selectedSection.value = [];
            attachFiles.value = [];
            replyUser.value = {};
        }

        function cancel() {
            context.emit('value', {
                msgInfo: MsgInfo.Cancel,
                text: null,
                mailTos: [],
                mailToSections: [],
                visibility: null,
                parentId: null,
                attachFiles: null
            });
            textValue.value = '';
            selectedPersonnels.value = [];
            selectedSection.value = [];
            attachFiles.value = [];
            replyUser.value = {};
        }

        const editor = ref<HTMLElement | null>(null);
        /** 获得焦点 */
        function editorFocus() {
            editor.value?.focus();
        }
        /**
         * 高级人员点确认
        */
        function selectionsChangePar(event: any) {
            if (event.data.users.length) {
                const userList: any = [];
                event.data.users.forEach((user: any) => {
                    userList.push(user.data);
                });
                appendPersonnelsList(userList);
            }
            if (event.data.section.length) {
                const sectionList: any = [];
                event.data.section.forEach((sec: any) => {
                    sectionList.push(sec.data);
                });
                appendSectionList(sectionList);
            }
            context.emit('selections', event);
        }
        /** 高级人员中选中某行 */
        function lineDataChangePar(event: any) {
            context.emit('lineData', event);
        }

        function outUsers(event: any) {
            context.emit('getOutUsers', event);
        }

        function activeStateChanged(item: any) {
            item.active = !item.active;
            return item;
        };

        return () => {
            return (
                <div class="f-discussion-editor">
                    {(replyUser.value && replyUser.value.id) && (
                        <div class="farris-discussion-group-reply-tip">
                            {'discussionGroup.reply'}
                            <span class="farris-discussion-group-reply-tip-name">
                                {replyUser.value[replyPersonnelsDisplayKey.value]}
                            </span>
                            ：
                        </div>
                    )}
                    <div class="f-discussion-group-edit">
                        <div class="f-discussion-group-edit-container"
                            style={[{ 'height': editHeight.value + 'px' }]}
                        >
                            <div class="textarea-editor"
                                onKeyup={(e) => listenEditorValueChange(e)}
                                onBlur={(e) => setTextValue(e)}
                                ref={editor}
                                contenteditable={true}
                                innerHTML={textValue.value}
                            ></div>
                        </div>
                        <div class="f-discussion-group-edit-footer">
                            <div class="f-discussion-group-edit-toolbar">
                                <div class="f-discussion-group-edit-toolbar-item f-discussion-group-edit-toolbar-about">
                                    <div class="toolbar-item-text" onClick={(e) => openModalPerson(e)}>
                                        <span class="toolbar-icon">@</span>
                                        <span class="toolbar-text">
                                            {'discussionGroup.colleague'}
                                        </span>
                                    </div>
                                    {personModalVisible.value && (
                                        <div class="f-discussion-group-about-dropdown" onClick={(e) => { stopBubble(e); }} ref={personModal} >
                                            <div class="f-discussion-group-about-search">
                                                <FInputGroup
                                                    placeholder={placeholder}
                                                    groupText={groupIcon}
                                                //  [(ngModel)]="personnelText"
                                                // enterHandle={searchPersonnel}
                                                // clickHandle={searchPersonnel}
                                                // valueChange={searchPersonnel}
                                                // clear={searchPersonnel}
                                                ></FInputGroup>
                                            </div>
                                            <div class="f-discussion-group-about-content">
                                                <div class="f-discussion-group-about-used" hidden={!!showSearchList.value}>
                                                    <ul class="f-discussion-group-about-dropdown-list">
                                                        {
                                                            innerPersonnels.length &&
                                                            (
                                                                innerPersonnels.map((item: any) => {
                                                                    return (
                                                                        <li
                                                                            onClick={activeStateChanged(item)}
                                                                            // "item.active = !item.active"
                                                                            class={["d-flex f-discussion-group-about-dropdown-list-item", { active: item.active }]}>
                                                                            <span class="f-icon f-icon-check"></span>
                                                                            {item.imgData && (
                                                                                <img src="item.imgData" class="about-list-item-avatar" />
                                                                            )}
                                                                            {!item.imgData && (
                                                                                <div class="about-list-item-avatar-tip" innerHTML={getAvatar(item)} ></div>
                                                                            )}
                                                                            <div class="f-discussion-group-about-dropdown-list-detail f-utils-fill">
                                                                                <div class="about-list-detail-text">{item[personnelsDisplayKey.value]}</div>
                                                                                <div class="about-list-detail-subtext">{item.email}</div>
                                                                            </div>
                                                                        </li>);
                                                                })
                                                            )}
                                                        {!innerPersonnels.length && (
                                                            <li class="f-discussion-group-about-dropdown-list-item about-dropdown-list-item-empty">
                                                                {'discussionGroup.emptyMessage'}
                                                            </li>)}
                                                    </ul>
                                                </div>
                                                <div class="f-discussion-group-about-searchlist" hidden={!showSearchList.value}>
                                                    <ul class="f-discussion-group-about-dropdown-list">
                                                        {searchPersonnelList && searchPersonnelList.users && searchPersonnelList.users.length && (
                                                            <template>
                                                                {searchPersonnelList.users.map((item: any) => {
                                                                    return (<li
                                                                        onClick={activeStateChanged(item)}
                                                                        // "item.active = !item.active"
                                                                        class={["d-flex f-discussion-group-about-dropdown-list-item", { 'active': item.active }]}>
                                                                        <span class="f-icon f-icon-check"></span>
                                                                        {item.imgData && (
                                                                            <img src="item.imgData" class="about-list-item-avatar" />
                                                                        )}
                                                                        {!item.imgData && (
                                                                            <div class="about-list-item-avatar-tip" innerHTML={getAvatar(item)}></div>)}
                                                                        <div class="f-discussion-group-about-dropdown-list-detail f-utils-fill">
                                                                            <div class="about-list-detail-text">{item[personnelsDisplayKey.value]}</div>
                                                                            <div class="about-list-detail-subtext"
                                                                            // innerHTML={item}
                                                                            // [innerHTML]="item | getOrgText:sectionData"
                                                                            ></div>
                                                                        </div>
                                                                    </li>);
                                                                })}

                                                                <div class="f-discussion-person-list-page">
                                                                    {searchPersonnelList.pageIndex < searchPersonnelList.pageCount - 1 && (
                                                                        <span class="section-page-more section-page-text"
                                                                            onClick={getMoreSearchData}>
                                                                            {'discussionGroup.viewMore'}
                                                                        </span>
                                                                    )}
                                                                </div>
                                                            </template>)}
                                                        {
                                                            searchPersonnelList && searchPersonnelList.users && !searchPersonnelList.users.length && (
                                                                <li class="f-discussion-group-about-dropdown-list-item about-dropdown-list-item-empty">
                                                                    {'discussionGroup.emptyMessage'}
                                                                </li>
                                                            )
                                                        }
                                                    </ul>
                                                </div>
                                            </div>
                                            <div class="f-about-list-btns d-flex">
                                                <div class="f-about-list-btns-left">
                                                    <farris-discussion-personnel
                                                        sectionData={sectionData.value}
                                                        orgUrl={orgUrl.value}
                                                        personSearchUrl={personSearchUrl.value}
                                                    // (selectionsChange)="selectionsChangePar($event)"
                                                    // (lineDataChange)="lineDataChangePar($event)"
                                                    // (outUsers)="outUsers($event)"
                                                    ></farris-discussion-personnel>
                                                </div>
                                                <div class="f-about-list-btns-right">
                                                    <button class="btn btn-secondary" onClick={resetPersonnels}>
                                                        {'discussionGroup.cancel'}
                                                    </button>
                                                    <button class="btn btn-primary" onClick={appendPersonnels}>
                                                        {'discussionGroup.confirm'}
                                                    </button>
                                                </div>
                                            </div>
                                        </div>

                                    )}

                                </div>
                            </div>
                            <div class="f-discussion-group-edit-btns">
                                {cancelVisible.value && (
                                    < button class="btn btn-link f-discussion-cancel" onClick={cancel}>
                                        {'discussionGroup.cancel'}</button>
                                )}

                                <button class="btn btn-primary"
                                    onClick={submitApproval}>
                                    {'discussionGroup.submit'}
                                </button>
                            </div>
                        </div>
                    </div >
                </div >
            );
        };
    }
});
